<?php

/**
 * Maikuro CMS
 *
 * LICENSE:
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * The license is bundled with this package in the file LICENSE.txt.
 * You may also obtain a copy of the License at this URL:
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @copyright  Copyright (c) 2010, Jonathan Hedrén
 * @author     Jonathan Hedrén <jonathan.hedren@gmail.com>
 * @license    http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

require_once 'Utility.php';

class PageTag
{
    private $page;

    /**
     *
     * @var FrontendApplicationContext
     */
    private $applicationContext;

    /**
     *
     * @var PageService
     */
    private $pageService;

    public function __construct(
            FrontendApplicationContext $applicationContext,
            PageService $pageService) {
        $this->applicationContext = $applicationContext;
        $this->pageService = $pageService;
    }

    public function ifTitle()
    {
        return ($this->hasPage() && !empty($this->getPage()->title));
    }

    public function ifContent()
    {
        return ($this->hasPage() && !empty ($this->getPage()->content));
    }

    public function ifCustomField()
    {
        // FIXME: Params: name="sidebar"
    }

    public function displayId(array $params)
    {
        return $this->hasPage() ? $this->getPage()->id : null;
    }

    public function displayContent(array $params)
    {
        return $this->hasPage() ? $this->getPage()->content : null;
    }


    public function displayCustomField(array $params)
    {
        $defaults = array(
            'class' => null,
            'id' => null,
            'name' => null,
            'wraptag' => null
        );

        $params = Utility::arrayOverlay($defaults, $params);

        $page = $this->getPage();
        
        if ($page != null && isset($page->customFields[$params['name']])) {
            $customField = $page->customFields[$params['name']];
            return $this->applicationContext
                        ->getTagParser()
                        ->parse($customField->value);
        }
        return null;
    }

    public function displayBreadcrumbs(array $params)
    {
        $defaults = array(
            'class' => null,
            'id' => null,
            'separator' => '>',
            'title' => 'You are here:',
            'wraptag' => 'div'
        );

        $params = Utility::arrayOverlay($defaults, $params);

        if (!$this->hasPage()) {
            return null;
        }

        $baseUrl = $this->applicationContext->getRequest()->getApplicationPath();
        
        $html = '';
        $page = $this->getPage();
        $html .= '<strong>' . $page->title . '</strong>';
        $hasDefaultPageParent = false;

        while (true) {
            $page = $this->pageService->getParentFor($page);
            if ($page == null) {
                break;
            }
            $html = '<a href="' . $baseUrl . $page->permalink . '">' . $page->title . '</a> ' . $params['separator'] . ' ' . $html;
        }

        $html = $params['title'] . ' ' . $html;
        $attributes = array(
            'id' => $params['id'],
            'class' => $params['class']
        );
        return $this->wrap($html, $params['wraptag'], $this->formatAttributes($attributes));
    }

    protected function wrap($html, $wrapTag = null, $attributes = null)
    {
        if ($wrapTag != null) {
            if ($wrapTag == 'br' || $wrapTag == 'hr') {
                return $html . '<' . $wrapTag . $attributes . ' />';
            }
            // FIXME: Man m�ste ju kunna wrap:a this->htmlEndTags[] ocks�...
            return '<' . $wrapTag . $attributes . '>' . $html . '</' . $wrapTag . '>';
        }
        return $html;
    }

    /**
     * Enter description here...
     *
     * @param string $name
     * @param mixed $value
     * @return string
     */
    protected function buildAttribute($name, $value = null)
    {
        if ($value != null && $value != '') {
            return ' ' . $name . '="' . $value . '"';
        }
    }

    /**
     * Enter description here...
     *
     * @param array $attributes
     * @return string
     */
    protected function formatAttributes(array $attributes)
    {
        $attributesAsString = '';
        foreach ($attributes as $name => $value) {
            if ($value != null) {
                $attributesAsString .= $this->buildAttribute($name, $value);
            }
        }
        return $attributesAsString;
    }

    public function displayChildren(array $params)
    {

        $defaults = array(
            'break'   => 'li',
            'wraptag' => 'ul',
            'wrapclass' => null,
            'wrapid' => null
        );

        $params = Utility::arrayOverlay($defaults, $params);

        $children = $this->pageService->getChildrenFor($this->applicationContext->getCurrentPage());

        if ($children === null) {
            return null;
        }
        $baseUrl = $this->applicationContext->getRequest()->getApplicationPath();

        extract($params);
        $output = '';
        foreach ($children as $child) {
            $output .= $this->wrap('<a href="'
                   . $baseUrl . $child->permalink
                   . '">' . $child->title . '</a>', $break);
        }
        return $this->wrap($output, $wraptag, $this->formatAttributes(array('class' => $wrapclass, 'id' => $wrapid)));
    }

    public function displayMenu(array $params)
    {
        $defaults = array(
            'class' => null,
            'id' => null,
            'rootpage' => null,
            'wraptag' => 'ul'
        );

        $params = Utility::arrayOverlay($defaults, $params);

        $baseUrl = $this->applicationContext->getRequest()->getApplicationPath();

        $menuPages = array();
        $rootPage = $this->pageService->getRootPage($this->applicationContext->getCurrentSite()->id);
        $menuPages[] = $rootPage;
        $menuPages = array_merge($menuPages, (array) $this->pageService->getChildrenFor($rootPage));
        
        $html = '<' . $params['wraptag'];
        if ($params['class']) {
            $html .= ' class="' . $params['class'] . '"';
        }
        if ($params['id']) {
            $html .= ' id="' . $params['id'] . '"';
        }
        $html .= '>';
        
        $currentPage = $this->applicationContext->getCurrentPage();

        foreach ($menuPages as $page) {
            $selected = '';
            if ($page->id == $currentPage->id
                    || ($this->pageService->isDescendantTo($currentPage, $page) && $page->id != $rootPage->id)) {
                $selected = ' class="selected"';
            }
            $html .= '<li' . $selected . '><a href="' . $baseUrl . $page->permalink . '">' . $page->title . '</a></li>';
        }
        
        $html .= '</ul>';

        return $html;
    }

    public function displayPermalink(array $params)
    {
        return $this->hasPage() ? $this->getPage()->permalink : null;
    }

    public function displayTitle(array $params)
    {
        return $this->hasPage() ? $this->getPage()->title : null;
    }

    public function displayUrlTitle(array $params)
    {
        return $this->hasPage() ? $this->getPage()->urlTitle : null;
    }

    public function displayTree(array $params)
    {
        return 'tree';
    }

    public function evaluate()
    {
        return $this->hasPage();
    }

    protected function getPage()
    {
        return $this->applicationContext->getCurrentPage();
    }

    protected function hasPage()
    {
        return ($this->applicationContext->getCurrentPage() !== null);
    }
}